home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / quicktime vr / vrscript.win / application files / comapplication.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  29.9 KB  |  925 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for scripting application.
  6. //                This file is used for ***BOTH*** MacOS and Windows.
  7. //
  8. //    Written by:    Tim Monroe
  9. //                Based on the MovieShell code written by Apple DTS.
  10. //
  11. //    Copyright:    © 1994-1998 by Apple Computer, Inc., all rights reserved.
  12. //
  13. //    Change History (most recent first):
  14. //
  15. //       <27>         12/17/98    rtm        added VRScript_SetCurrentDirectory call to InitApplicationWindowObject; now the
  16. //                                    initial current directory is that of the movie file in all cases
  17. //       <26>         12/03/98    rtm        added MoviesTask call to DoIdle for QuickTime movies, so they continue to play
  18. //                                    even while a dialog box (for instance, the About box) is displayed
  19. //       <25>         12/02/98    rtm        added previous movie/controller disposal code to DoApplicationEventLoopAction 
  20. //       <24>         11/23/98    rtm        HandleOpenDocumentAppleEvent now accepts dropped movie files too; added call
  21. //                                    to DoOpenCommandLineMovies back to InitApplication; the end result of all this
  22. //                                    is that both Mac and Windows apps will now open either movie files or scripts
  23. //                                    dropped onto the applicaiton icon
  24. //       <23>         11/14/98    rtm        InitApplication now calls VRScript_OpenCommandLineScriptFile instead of
  25. //                                    DoOpenCommandLineMovies, so we can drop scripts onto the application icon
  26. //                                    under Windows (MacOS was previously supported using AppleEvents)
  27. //       <22>         06/19/98    rtm        added mcActionMouseDown case to ApplicationMCActionFilterProc; also added
  28. //                                    other code for sprite track support
  29. //       <21>         03/12/98    rtm        added mcActionCustomButtonClick case to ApplicationMCActionFilterProc
  30. //       <20>         10/27/97    rtm        began adding support for QuickTime video effects
  31. //       <19>         10/23/97    rtm        moved InitializeQTVR to InitApplication, TerminateQTVR to StopApplication
  32. //       <18>         10/13/97    rtm        reworked HandleApplicationMenu to use menu item identifiers
  33. //       <17>         10/10/97    rtm        StopApplication now executes quitting-time commands for all open document windows;
  34. //                                    also, added phases for StopApplication
  35. //       <16>         09/24/97    rtm        upgraded to latest QuickTime VR headers
  36. //       <15>         09/18/97    rtm        added window-walking logic to DoApplicationEventLoopAction
  37. //       <14>         09/11/97    rtm        merged MacApplication.c and WinApplication.c into ComApplication.c
  38. //       <13>         08/21/97    rtm        first file for Windows; based on MacApplication.c for Mac sample code
  39. //       <12>         07/23/97    rtm        moved VRScript_CheckForTimedCommands back to DoIdle
  40. //       <11>         07/17/97    rtm        reworked DoIdle; added call to VR3DObjects_DoIdle
  41. //       <10>         07/15/97    rtm        moved VRScript_CheckForTimedCommands call from DoIdle to DoApplicationEventLoopAction
  42. //       <9>         07/14/97    rtm        fixed bug in DoIdle: put timer variable updates before _Check calls
  43. //       <8>         07/11/97    rtm        added DoApplicationEventLoopAction
  44. //       <7>         06/12/97    rtm        script file now can specify the movie file
  45. //       <6>         06/11/97    rtm        added handlers for core Apple events
  46. //       <5>         12/11/96    rtm        begun QuickTime movie work
  47. //       <4>         12/05/96    rtm        added hooks into MacFramework.c: StopApplication, InitApplicationWindowObject
  48. //       <3>         12/02/96    rtm        added cursor updating to DoIdle
  49. //       <2>         11/27/96    rtm        conversion to personal coding style; added preliminary QTVR support
  50. //       <1>         12/21/94    khs        first file
  51. //
  52. //////////
  53.  
  54. // header files
  55. #include "ComApplication.h"
  56.  
  57. // global variables for Macintosh code
  58. #if TARGET_OS_MAC
  59. Str255                    gAppName = "\pVRScript";                // the name of this application
  60. AEEventHandlerUPP        gHandleOpenAppAEUPP;                    // UPPs for our Apple event handlers
  61. AEEventHandlerUPP        gHandleOpenDocAEUPP;
  62. AEEventHandlerUPP        gHandlePrintDocAEUPP;
  63. AEEventHandlerUPP        gHandleQuitAppAEUPP;
  64. #endif
  65.  
  66. // global variables for Windows code
  67. #if TARGET_OS_WIN32
  68. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  69. extern int                gNumWindowsOpen;
  70. extern LPSTR            gCmdLine;
  71. #endif
  72.  
  73. // global variables for common code
  74. long                    gMaxMilliSecToUse = 0L;        
  75. Boolean                    gQTVRMgrIsPresent = false;                // is the QuickTime VR Manager available?        
  76. long                    gQTVRMgrVersion = 0L;                    // the version of the QuickTime VR Manager (currently unused)
  77. Boolean                    gHasSoundSprockets = false;                // is SoundSprockets available?
  78. long                    gAbsoluteStartingTime = 0L;                // starting time, in ticks
  79. long                    gAbsoluteElapsedTime = 0L;                // total elapsed time, in ticks
  80. long                    gNodeStartingTime = 0L;                    // node starting time, in ticks
  81. long                    gNodeElapsedTime = 0L;                    // node elapsed time, in ticks
  82.  
  83. Boolean                    gHasQuickDraw3D = false;                // is QuickDraw 3D available?
  84. Boolean                    gHasQuickDraw3D15 = false;                // is QuickDraw 3D version 1.5 (or greater) available?
  85.  
  86. Boolean                    gHasQTVideoEffects = false;                // are the QuickTime video effects available?
  87.  
  88. // external variables
  89. extern Boolean            gAppInForeground;                        // is our application in the foreground?    
  90. extern char                gScriptFileName[kMaxFileNameLength];    // the name of the script file
  91. extern MovieController    gPreviousMC;                            // a controller that's been replaced by a call to ReplaceMainMovie                
  92. extern Movie            gPreviousMovie;                            // a movie that's been replaced by a call to ReplaceMainMovie        
  93.  
  94.  
  95. //////////
  96. //
  97. // InitApplication
  98. // Do any application-specific initialization.
  99. //
  100. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  101. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  102. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  103. //
  104. //////////
  105.  
  106. void InitApplication (UInt32 theStartPhase)
  107. {
  108.     // ***do any start-up activities that should occur before the MDI frame window is created
  109.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  110.  
  111.         // see if the QuickTime video effects are available
  112.         gHasQTVideoEffects = QTUtils_HasQuickTimeVideoEffects();
  113.     
  114.         // make sure that the QuickTime VR Manager is available in the present operating environment;
  115.         // if it is, get its version and initialize it
  116.         if (QTVRUtils_IsQTVRMgrInstalled()) {
  117.             gQTVRMgrIsPresent = true;
  118.             gQTVRMgrVersion = QTVRUtils_GetQTVRVersion();
  119.         
  120. #if TARGET_OS_WIN32
  121.             // initialize the QuickTime VR Manager
  122.             InitializeQTVR();
  123. #endif
  124.         }
  125.     
  126. #if TARGET_OS_MAC
  127.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  128.         InstallAppleEventHandlers();
  129. #endif
  130.  
  131.         // create the hash table
  132.         VRHash_CreateHashTable();
  133.  
  134.         // initialize sound capabilities
  135.         VRSound_Init();
  136.  
  137. #if QD3D_AVAIL
  138.         // initialize 3D object capabilities
  139.         VR3DObjects_Init();
  140. #endif
  141.     
  142.         // get the application-launch starting time 
  143.         gAbsoluteStartingTime = TickCount();
  144.         
  145.     }    // end of kInitAppPhase_BeforeCreateFrameWindow
  146.  
  147.     // ***do any start-up activities that should occur after the MDI frame window is created
  148.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  149.         
  150. #if TARGET_OS_WIN32
  151.         // on Windows, open as *scripts* any text files specified on the command line
  152.         VRScript_OpenCommandLineScriptFile(gCmdLine);    
  153.                                         
  154.         // on Windows, open as *movies* any movie files specified on the command line
  155.         DoOpenCommandLineMovies(gCmdLine);                                    
  156. #endif
  157.     }    // end of kInitAppPhase_AfterCreateFrameWindow
  158.  
  159. }
  160.  
  161.  
  162. //////////
  163. //
  164. // StopApplication
  165. // Do any application-specific shut-down.
  166. //
  167. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  168. // *before* any open movie windows are destroyed or *after*.
  169. //
  170. //////////
  171.  
  172. void StopApplication (UInt32 theStopPhase)
  173. {
  174.     WindowReference            myWindow;
  175.     WindowObject            myWindowObject;
  176.     
  177.     // do any shut-down activities that should occur before the movie windows are destroyed
  178.     if (theStopPhase & kStopAppPhase_BeforeDestroyWindows) {
  179.  
  180.         // execute any quitting-time commands for all open document windows
  181.         myWindow = GetFrontMovieWindow();
  182.         while (myWindow != NULL) {
  183.         
  184.             myWindowObject = GetWindowObjectFromWindow(myWindow);
  185.             if (myWindowObject != NULL) {
  186.                 ApplicationDataHdl        myAppData;
  187.             
  188.                 myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  189.                 if (myAppData != NULL) {
  190.                     VRScriptAtQuitPtr    myPointer;
  191.                     
  192.                     myPointer = (VRScriptAtQuitPtr)(**myAppData).fListArray[kVREntry_QuitCommand];
  193.                     while (myPointer != NULL) {
  194.                         VRScript_ProcessScriptCommandLine(myWindowObject, myPointer->fCommandLine);
  195.                         myPointer = myPointer->fNextEntry;
  196.                     }
  197.                 }
  198.             }
  199.             
  200.             myWindow = GetNextMovieWindow(myWindow);
  201.         }
  202.     
  203.     }    // end of kStopAppPhase_BeforeDestroyWindows
  204.     
  205.     // do any shut-down activities that should occur after the movie windows are destroyed
  206.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  207.     
  208.         // shut down sound processing
  209.         VRSound_Stop();
  210.  
  211. #if QD3D_AVAIL
  212.         // shut down 3D object capabilities, if enabled
  213.         VR3DObjects_Stop();
  214. #endif
  215.  
  216.         // dispose of our hash table
  217.         VRHash_DestroyHashTable();
  218.  
  219. #if TARGET_OS_MAC
  220.         // dispose of routine descriptors for Apple event handlers
  221.         DisposeRoutineDescriptor(gHandleOpenAppAEUPP);
  222.         DisposeRoutineDescriptor(gHandleOpenDocAEUPP);
  223.         DisposeRoutineDescriptor(gHandlePrintDocAEUPP);
  224.         DisposeRoutineDescriptor(gHandleQuitAppAEUPP);
  225. #endif
  226.     
  227. #if TARGET_OS_WIN32
  228.         // terminate QuickTime VR Manager
  229.         if (gQTVRMgrIsPresent)
  230.             TerminateQTVR();
  231. #endif
  232.             
  233.     }    // end of kStopAppPhase_AfterDestroyWindows
  234.     
  235. }
  236.  
  237.  
  238. //////////
  239. //
  240. // DoIdle
  241. // Do any processing that can/should occur at idle time.
  242. //
  243. //////////
  244.  
  245. void DoIdle (WindowReference theWindow)
  246. {
  247.     WindowObject         myWindowObject = NULL;
  248.     GrafPtr             mySavedPort;
  249.     
  250.     GetPort(&mySavedPort);
  251.     MacSetPort(GetPortFromWindowReference(theWindow));
  252.     
  253.     // update our timer global variables; this also happens in DoApplicationEventLoopAction
  254.     gAbsoluteElapsedTime = TickCount() - gAbsoluteStartingTime; 
  255.     gNodeElapsedTime = TickCount() - gNodeStartingTime;
  256.     
  257.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  258.     if (myWindowObject != NULL) {
  259.         MovieController        myMC = NULL;
  260.         ApplicationDataHdl    myAppData = NULL;
  261.         Boolean                myNeedUpdate = false;
  262.     
  263.         myMC = (**myWindowObject).fController;
  264.         if (myMC != NULL) {
  265.             
  266. #if TARGET_OS_MAC
  267.             // restore the cursor to the arrow
  268.             // if it's outside the front movie window or outside the window's visible region
  269.             if (theWindow == GetFrontMovieWindow()) {
  270.                 Rect    myRect;
  271.                 Point    myPoint;
  272.                 
  273.                 GetMouse(&myPoint);
  274.                 MCGetControllerBoundsRect(myMC, &myRect);
  275.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, GetPortFromWindowReference(theWindow)->visRgn))
  276.                     MacSetCursor(&qd.arrow);
  277.             }
  278. #endif
  279.         }
  280.         
  281.         // if the main window contains a QuickTime movie, give it some time
  282.         if ((**myWindowObject).fInstance == NULL)
  283.             MoviesTask((**myWindowObject).fMovie, 0L);
  284.  
  285.         // see whether we need to execute any time-triggered commands
  286.         VRScript_CheckForTimedCommands(myWindowObject);
  287.  
  288.         // see whether we need to execute any angle-triggered commands
  289.         VRScript_CheckForAngleCommands(myWindowObject);
  290.  
  291.         // if any view parameters have changed, we need to update window        
  292.         myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  293.         if (myAppData != NULL)
  294.             if ((**myAppData).fViewHasChanged || (**myAppData).fSoundHasChanged) 
  295.                 myNeedUpdate = true;
  296.                 
  297.         // give any embedded QuickTime movies some processor time
  298.         myNeedUpdate |= VRMoov_DoIdle(myWindowObject);
  299.         
  300.         // give any QuickTime video effects some processor time
  301.         if (gHasQTVideoEffects)
  302.             myNeedUpdate |= VREffects_DoIdle(myWindowObject);
  303.         
  304. #if QD3D_AVAIL
  305.         // give 3D animation and texture-mapping some processor time
  306.         if (gHasQuickDraw3D)
  307.             myNeedUpdate |= VR3DObjects_DoIdle(myWindowObject);
  308. #endif
  309.  
  310.         if (myNeedUpdate)
  311.             QTVRUpdate((**myWindowObject).fInstance, kQTVRCurrentMode);
  312.     }
  313.  
  314.     MacSetPort(mySavedPort);
  315. }
  316.  
  317.  
  318. //////////
  319. //
  320. // DoUpdateWindow
  321. // Update the specified window.
  322. //
  323. //////////
  324.  
  325. void DoUpdateWindow (WindowReference theWindow, Rect *theRefreshArea)
  326. {
  327. #pragma unused(theRefreshArea)
  328.     GrafPtr             mySavedPort;
  329.     
  330.     GetPort(&mySavedPort);
  331.     MacSetPort(GetPortFromWindowReference(theWindow));
  332.     
  333.     BeginUpdate(GetPortFromWindowReference(theWindow));
  334.     
  335.     // draw the movie controller and its movie
  336.     MCDoAction(GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  337.     
  338.     EndUpdate(GetPortFromWindowReference(theWindow));
  339.     MacSetPort(mySavedPort);
  340. }
  341.  
  342.  
  343. //////////
  344. //
  345. // HandleContentClick
  346. // Handle mouse button clicks in the specified window.
  347. //
  348. //////////
  349.  
  350. void HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  351. {
  352. #pragma unused(theWindow, theEvent)
  353.  
  354.     //GrafPtr             mySavedPort;
  355.     
  356.     //GetPort(&mySavedPort);
  357.     //MacSetPort(GetPortFromWindowReference(theWindow));
  358.     
  359.     // @@@INSERT APPLICATION-SPECIFIC CONTENT CLICKING FUNCTIONALITY HERE
  360.  
  361.     //MacSetPort(mySavedPort);
  362. }
  363.  
  364.  
  365. //////////
  366. //
  367. // HandleApplicationKeyPress
  368. // Handle application-specific key presses.
  369. // Returns true if the key press was handled, false otherwise.
  370. //
  371. //////////
  372.  
  373. Boolean HandleApplicationKeyPress (char theCharCode)
  374. {
  375.     Boolean            isHandled = true;    // assume we'll handle the key press
  376.     QTVRInstance    myInstance;
  377.     
  378.     // make sure we can safely call the QTVR API
  379.     if (!gQTVRMgrIsPresent)
  380.         return(false);
  381.     
  382.     myInstance = GetQTVRInstanceFromFrontWindow();
  383.     if (myInstance == NULL)
  384.         return(false);
  385.     
  386.     switch (theCharCode) {
  387.         // take keypad keys as a nudge in the appropriate direction
  388.         case '1':    QTVRNudge(myInstance, kQTVRDownLeft);        break;
  389.         case '2':    QTVRNudge(myInstance, kQTVRDown);            break;
  390.         case '3':    QTVRNudge(myInstance, kQTVRDownRight);        break;
  391.         case '4':    QTVRNudge(myInstance, kQTVRLeft);            break;
  392.         case '6':    QTVRNudge(myInstance, kQTVRRight);            break;
  393.         case '7':    QTVRNudge(myInstance, kQTVRUpLeft);            break;
  394.         case '8':    QTVRNudge(myInstance, kQTVRUp);                break;
  395.         case '9':    QTVRNudge(myInstance, kQTVRUpRight);        break;    
  396.         default:
  397.             isHandled = false;
  398.             break;
  399.     }
  400.  
  401.     if (isHandled)
  402.         QTVRUpdate(myInstance, kQTVRCurrentMode);
  403.         
  404.     return(isHandled);
  405. }
  406.  
  407.  
  408. #if TARGET_OS_MAC
  409. //////////
  410. //
  411. // CreateMovieWindow
  412. // Create a window to display a movie in.
  413. //
  414. //////////
  415.  
  416. WindowRef CreateMovieWindow (Rect *theRect, Str255 theTitle)
  417. {
  418.     WindowRef            myWindow;
  419.         
  420.     myWindow = NewCWindow(NULL, theRect, theTitle, false, noGrowDocProc, (WindowPtr)-1L, true, 0);
  421.     return(myWindow);
  422. }
  423. #endif
  424.  
  425.  
  426. //////////
  427. //
  428. // HandleApplicationMenu
  429. // Handle selections in the application's menus.
  430. //
  431. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  432. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window proc.
  433. // When called from MacOS, theMenuItem is constructed like this:
  434. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  435. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  436. // In this way, we can simplify the menu-handling code. There are, however, some limitations,
  437. // mainly that the menu item identifiers on Windows must be derived from the Mac values. 
  438. //
  439. //////////
  440.  
  441. void HandleApplicationMenu (UInt16 theMenuItem)
  442. {
  443. #pragma unused(theMenuItem)
  444.     // currently, we don't have any application-specific menus to handle
  445. }
  446.  
  447.  
  448. //////////
  449. //
  450. // AdjustApplicationMenus
  451. // Adjust state of items in the application's menus.
  452. //
  453. //////////
  454.  
  455. void AdjustApplicationMenus (WindowReference theWindow, MenuReference theMenu)
  456. {
  457. #pragma unused(theWindow, theMenu)
  458.     // currently, we don't have any application-specific menus to adjust
  459. }
  460.  
  461.  
  462. //////////
  463. //
  464. // DoApplicationEventLoopAction
  465. // Perform any application-specific event loop actions.
  466. //
  467. // Return true to indicate that we've completely handled the event here, false otherwise.
  468. //
  469. //////////
  470.  
  471. Boolean DoApplicationEventLoopAction (EventRecord *theEvent)
  472. {
  473. #pragma unused(theEvent)
  474.     
  475.     WindowReference        myWindow;
  476.     WindowObject        myWindowObject;
  477.  
  478.     // update our timer global variables; this also happens in DoIdle
  479.     gAbsoluteElapsedTime = TickCount() - gAbsoluteStartingTime; 
  480.     gNodeElapsedTime = TickCount() - gNodeStartingTime;
  481.      
  482.     // check for completed sounds and movies in all open movie windows
  483.     myWindow = GetFrontMovieWindow();
  484.  
  485.     while (myWindow != NULL) {
  486.         myWindowObject = GetWindowObjectFromWindow(myWindow);
  487.         if (myWindowObject != NULL) {
  488.             // check for completed sounds and movies
  489.             VRSound_CheckForCompletedSounds(myWindowObject);
  490.             VRMoov_CheckForCompletedMovies(myWindowObject);
  491.         }
  492.  
  493.         myWindow = GetNextMovieWindow(myWindow);
  494.  
  495.     }    // while
  496.     
  497.     // see whether we need to dispose of any replaced movie and controller
  498.     if (gPreviousMC != NULL) {
  499.         DisposeMovieController(gPreviousMC);
  500.         gPreviousMC = NULL;
  501.     }
  502.     
  503.     if (gPreviousMovie != NULL) {
  504.         DisposeMovie(gPreviousMovie);
  505.         gPreviousMovie = NULL;
  506.     }
  507.     
  508.     return(false);        // we didn't intercept the event
  509. }
  510.  
  511.  
  512. //////////
  513. //
  514. // AddControllerFunctionality
  515. // Configure the movie controller.
  516. //
  517. //////////
  518.  
  519. void AddControllerFunctionality (MovieController theMC)
  520. {
  521.     long            myControllerFlags;
  522.     
  523.     // CLUT table use    
  524.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  525.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  526.  
  527.     // enable keyboard event handling    
  528.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  529.     
  530.     // disable drag support
  531.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  532. }
  533.  
  534.  
  535. //////////
  536. //
  537. // InitApplicationWindowObject
  538. // Do any application-specific initialization of the window object.
  539. //
  540. //////////
  541.  
  542. void InitApplicationWindowObject (WindowObject theWindowObject)
  543. {
  544.     Track                    myQTVRTrack = NULL;
  545.     Movie                    myMovie = NULL;
  546.     MovieController            myMC = NULL;
  547.     QTVRInstance            myInstance = NULL;
  548.     ApplicationDataHdl        myAppData;
  549.         
  550.     if (theWindowObject == NULL)
  551.         return;
  552.  
  553.     // make sure we can safely call the QTVR API
  554.     if (!gQTVRMgrIsPresent)
  555.         return;
  556.  
  557.     // find the QTVR track, if there is one
  558.     myMC = (**theWindowObject).fController;
  559.     myMovie = (**theWindowObject).fMovie;
  560.     myQTVRTrack = QTVRGetQTVRTrack(myMovie, 1);
  561.     
  562.     QTVRGetQTVRInstance(&myInstance, myQTVRTrack, myMC);
  563.     (**theWindowObject).fInstance = myInstance;
  564.  
  565.     // do any application-specific window configuration
  566.     if (myInstance != NULL) {
  567.         
  568.         // set unit to radians
  569.         QTVRSetAngularUnits(myInstance, kQTVRRadians);
  570.  
  571.         // do window configuration
  572.         myAppData = (ApplicationDataHdl)NewHandleClear(sizeof(ApplicationDataRecord));
  573.         (**theWindowObject).fAppData = (Handle)myAppData;        
  574.         if (myAppData != NULL) {
  575.             
  576.             // initialize for sounds
  577.             VRSound_InitWindowData(theWindowObject);
  578.  
  579. #if QD3D_AVAIL
  580.             // initialize for 3D objects
  581.             if (gHasQuickDraw3D)
  582.                 VR3DObjects_InitWindowData(theWindowObject);
  583. #endif
  584.             // initialize for QuickTime video effects
  585.             if (gHasQTVideoEffects)
  586.                 VREffects_InitWindowData(theWindowObject);
  587.  
  588.             // initialize for sprites
  589.             VRSprites_InitWindowData(theWindowObject);
  590.  
  591.             // allocate a routine descriptor for our prescreen routine                        
  592.             (**myAppData).fPrescreenProc = NewQTVRImagingCompleteProc(VRScript_PrescreenRoutine);    
  593.  
  594.             // install an intercept procedure and a prescreen procedure
  595.             VRScript_InstallInterceptRoutine(myInstance, theWindowObject);
  596.             VRScript_InstallPrescreenRoutine(myInstance, theWindowObject);
  597.             
  598.             // install node-entering and node-leaving procedures
  599.             QTVRSetEnteringNodeProc(myInstance, NewQTVREnteringNodeProc(VRScript_EnteringNodeProc), (SInt32)theWindowObject, 0);
  600.             QTVRSetLeavingNodeProc(myInstance, NewQTVRLeavingNodeProc(VRScript_LeavingNodeProc), (SInt32)theWindowObject, 0);
  601.             
  602.             // install hot spot procedures
  603.             VRScript_InstallHotSpotInterceptProc(myInstance, theWindowObject);
  604.             VRScript_InstallMouseOverHotSpotProc(myInstance, theWindowObject);
  605.                 
  606.             // read the command script file;
  607.             // if the user launched the application by dropping a script file onto the application's icon,
  608.             // then we already know the name of the script file to open (it's stored in gScriptFileName);
  609.             // otherwise, look for a script file called "myScript" in the same directory as the QTVR movie
  610.             // file
  611.             
  612.             if (strlen(gScriptFileName) > 0) {
  613.                 VRScript_OpenScriptFile(theWindowObject, gScriptFileName);
  614.             } else {
  615.                 VRScript_SetCurrentDirectory(&(**theWindowObject).fFileFSSpec);
  616.                 VRScript_OpenScriptFile(theWindowObject, kDefaultScriptFileName);
  617.             }
  618.             
  619.             // ***TESTING***
  620.             // this is a good place to test out commands without having to read them from a script file
  621.             if (false) {
  622.                 //char    myCmdLine1[kMaxCmdLineLength] = "AtClickSprite 1 -1 2 SetSpriteMatrix#2#1.0#0.0#0.0#0.0#1.0#0.0#140.0#160.0#1.0#0";
  623.                 //char    myCmdLine2[kMaxCmdLineLength] = "AtTime 300 1 1 0 0 1     0 ReplaceMainMovie#0#0#0#OfficePano";
  624.                 //char    myCmdLine2[kMaxCmdLineLength] = "AtClickHS 1 50 -1 1 ReplaceMainMovie#0#2#0#file:///Meditations/WiredSprite.mov";
  625.                 //char    myCmdLine2[kMaxCmdLineLength] = "AtClickHS 1 50 -1 1 ReplaceMainMovie#0#0#0#Meditations:WiredSprite.mov";
  626.                 //char    myCmdLine3[kMaxCmdLineLength] = "OpenResourceFile    0            myCursors";
  627.                 //char    myCmdLine4[kMaxCmdLineLength] = "AtClickCustomButton    -1    -1    0        Beep";
  628.                 //char    myCmdLine4[kMaxCmdLineLength] = "PlaySceneQTMidi 144 1 1.0 0.0 0.0 180.0 0 0 2 myFile.mov";
  629.                 
  630.                 //VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine1);
  631.                 //VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine2);
  632.                 //VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine3);
  633.                 //VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine4);
  634.             }
  635.             // ***TESTING***
  636.             
  637.             // initialize for first node
  638.             (**myAppData).fViewHasChanged = true;
  639.             (**myAppData).fSoundHasChanged = true;
  640.             
  641.             // node-entering procedure is NOT automatically called for the first node, so do it now....
  642.             VRScript_EnteringNodeProc(myInstance, QTVRGetCurrentNodeID(myInstance), theWindowObject);
  643.             
  644.             QTVRUpdate(myInstance, kQTVRCurrentMode);
  645.         }
  646.     }
  647. }
  648.  
  649.  
  650. //////////
  651. //
  652. // RemoveApplicationWindowObject
  653. // Do any application-specific clean-up of the window object.
  654. //
  655. //////////
  656.  
  657. void RemoveApplicationWindowObject (WindowObject theWindowObject)
  658. {
  659.     ApplicationDataHdl    myAppData;
  660.     
  661.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  662.     if (myAppData == NULL)
  663.         return;
  664.  
  665.     VRSound_DumpWindowData(theWindowObject);
  666.     VRMoov_DumpNodeMovies(theWindowObject);
  667.     VRMoov_DumpSceneMovies(theWindowObject);
  668.  
  669. #if QD3D_AVAIL
  670.     // clean-up after QuickDraw 3D
  671.     if (gHasQuickDraw3D)
  672.         VR3DObjects_DumpWindowData(theWindowObject);
  673. #endif
  674.         
  675.     // clean-up after QuickTime video effects
  676.     if (gHasQTVideoEffects)
  677.         VREffects_DumpWindowData(theWindowObject);
  678.  
  679.     // clean-up sprites
  680.     VRSprites_DumpWindowData(theWindowObject);
  681.  
  682. #if TARGET_OS_MAC
  683.     // get rid of routine descriptors
  684.     DisposeRoutineDescriptor((**myAppData).fPrescreenProc);
  685.     DisposeRoutineDescriptor((**myAppData).fBackBufferProc);
  686. #endif
  687.         
  688.     // get rid of linked lists
  689.     VRScript_DeleteAllLists(theWindowObject);
  690.             
  691.     // get rid of window data
  692.     DisposeHandle((Handle)myAppData);
  693.         
  694.     // DoDestroyMovieWindow in MacFramework.c or MovieWndProc in WinFramework.c
  695.     // releases the window object itself
  696. }
  697.  
  698.  
  699. //////////
  700. //
  701. // ApplicationMCActionFilterProc 
  702. // Intercept some mc actions for the QuickTime or QuickTime VR movie controller.
  703. //
  704. // NOTE: The theRefCon parameter is a handle to a window object record.
  705. //
  706. //////////
  707.  
  708. PASCAL_RTN Boolean ApplicationMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  709. {
  710. #pragma unused(theMC)
  711.  
  712.     Boolean                    isHandled = false;
  713.     WindowObject            myWindowObject = NULL;
  714.     ApplicationDataHdl        myAppData;
  715.     
  716.     if (theMC == NULL)
  717.         return(isHandled);
  718.         
  719.     myWindowObject = (WindowObject)theRefCon;
  720.     if (myWindowObject == NULL)
  721.         return(isHandled);
  722.         
  723.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  724.  
  725.     switch (theAction) {
  726.     
  727.         // handle window resizing
  728.         case  mcActionControllerSizeChanged:
  729.             SizeWindowToMovie(myWindowObject);
  730.             
  731.             // because the window size has changed, 
  732.             // we need to recalculate QD3D camera's aspect ratio and resize the QD3D draw context
  733. #if QD3D_AVAIL
  734.             if ((**myWindowObject).fInstance != NULL)
  735.                 if (gHasQuickDraw3D) {
  736.                     VR3DObjects_SetCameraAspectRatio(myWindowObject);                                 
  737.                     VR3DObjects_UpdateDrawContext(myWindowObject);                                 
  738.                     QTVRUpdate((**myWindowObject).fInstance, kQTVRCurrentMode);
  739.                 }
  740. #endif
  741.             break;
  742.             
  743.         // handle idle events
  744.         case mcActionIdle:
  745.             DoIdle((**myWindowObject).fWindow);
  746.             break;
  747.             
  748.         // handle update events
  749.         case mcActionDraw:
  750.             break;
  751.  
  752.         // handle custom controller button clicks
  753.         case mcActionCustomButtonClick:
  754.             // good human interface design would have us track the cursor and process the mouse-down event
  755.             // only if the subsequent mouse-up event occurs inside of the custom button rectangle; however,
  756.             // we have no way of getting the custom button rectangle; so, we just blindly plow on ahead....
  757.             VRScript_CheckForClickCustomButtonCommands(myWindowObject, (EventRecord *)theParams);
  758.             break;
  759.             
  760.         // handle mouse-down events
  761.         case mcActionMouseDown:
  762.             // look for and handle sprite clicks, but only if the movie has a sprite track
  763.             if (myAppData != NULL)
  764.                 if ((**myAppData).fMovieHasSprites)
  765.                     isHandled = VRScript_CheckForClickSpriteCommands(myWindowObject, (EventRecord *)theParams);
  766.             break;
  767.             
  768.         default:
  769.             break;
  770.             
  771.     }    // switch (theAction)
  772.     
  773.     return(isHandled);    
  774. }
  775.  
  776.  
  777. #if TARGET_OS_MAC
  778. //////////
  779. //
  780. // InstallAppleEventHandlers 
  781. // Install handlers for Apple events.
  782. //
  783. //////////
  784.  
  785. void InstallAppleEventHandlers (void)
  786. {
  787.     long        myAttrs;
  788.     OSErr        myErr = noErr;
  789.     
  790.     // see whether the Apple Event Manager is available in the present operating environment;
  791.     // if it is, install handlers for the four required Apple events
  792.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  793.     if (myErr == noErr) {
  794.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  795.             // create routine descriptors for the Apple event handlers
  796.             gHandleOpenAppAEUPP = NewAEEventHandlerProc(HandleOpenApplicationAppleEvent);
  797.             gHandleOpenDocAEUPP = NewAEEventHandlerProc(HandleOpenDocumentAppleEvent);
  798.             gHandlePrintDocAEUPP = NewAEEventHandlerProc(HandlePrintDocumentAppleEvent);
  799.             gHandleQuitAppAEUPP = NewAEEventHandlerProc(HandleQuitApplicationAppleEvent);
  800.             
  801.             // install the handlers
  802.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  803.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  804.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  805.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  806.         }
  807.     }
  808. }
  809.         
  810.         
  811. //////////
  812. //
  813. // HandleOpenApplicationAppleEvent 
  814. // Handle the open-application Apple event.
  815. //
  816. //////////
  817.  
  818. PASCAL_RTN OSErr HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  819. {
  820. #pragma unused(theMessage, theReply, theRefcon)
  821.  
  822.     // we don't need to do anything special when opening the application
  823.     return(noErr);
  824. }
  825.  
  826.  
  827. //////////
  828. //
  829. // HandleOpenDocumentAppleEvent 
  830. // Handle the open-document Apple event. This is based on Inside Macintosh: IAC, pp. 4-15f.
  831. //
  832. // Here we process an Open Documents AE only for files of type kScriptFileType and creator kScriptFileCreator,
  833. // and for files of type MovieFileType.
  834. //
  835. //////////
  836.  
  837. PASCAL_RTN OSErr HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  838. {
  839. #pragma unused(theReply, theRefcon)
  840.  
  841.     long            myIndex;
  842.     long            myItemsInList;
  843.     AEKeyword        myKeyWd;
  844.     AEDescList          myDocList;
  845.     long            myActualSize;
  846.     DescType        myTypeCode;
  847.     FSSpec            myFSSpec;
  848.     OSErr            myIgnoreErr = noErr;
  849.     OSErr            myErr = noErr;
  850.     
  851.     // get the direct parameter and put it into myDocList
  852.     myDocList.dataHandle = NULL;
  853.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  854.     
  855.     // count the descriptor records in the list
  856.     if (myErr == noErr)
  857.         myErr = AECountItems(&myDocList, &myItemsInList);
  858.     else
  859.         myItemsInList = 0;
  860.     
  861.     // open each specified file
  862.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  863.         if (myErr == noErr) {
  864.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  865.             if (myErr == noErr) {
  866.                 FInfo        myFinderInfo;
  867.             
  868.                 // verify that the file type is kScriptFileType and the creator is kScriptFileCreator;
  869.                 // to do this, get the Finder information
  870.                 myErr = FSpGetFInfo(&myFSSpec, &myFinderInfo);    
  871.                 if (myErr == noErr) {
  872.                     if ((myFinderInfo.fdType == kScriptFileType) && (myFinderInfo.fdCreator == kScriptFileCreator))
  873.                         // we've got a script file; find the target QTVR movie and open it
  874.                         VRScript_FindAndOpenQTVRMovieFile(&myFSSpec);
  875.                         
  876.                     if (myFinderInfo.fdType == MovieFileType)
  877.                         // we've got a movie file; just open it
  878.                         DoCreateMovieWindow(NULL, &myFSSpec);
  879.                 }
  880.             }
  881.         }
  882.  
  883.     if (myDocList.dataHandle)
  884.         myIgnoreErr = AEDisposeDesc(&myDocList);
  885.     
  886.     // make sure we open the document in the foreground        
  887.     gAppInForeground = true;
  888.     return(myErr);
  889. }
  890.  
  891.  
  892. //////////
  893. //
  894. // HandlePrintDocumentAppleEvent 
  895. // Handle the print-document Apple event.
  896. // NOT YET IMPLEMENTED: because we don't want to print our scripts, just act on them.
  897. //
  898. //////////
  899.  
  900. PASCAL_RTN OSErr HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  901. {
  902. #pragma unused(theMessage, theReply, theRefcon)
  903.  
  904.     return(errAEEventNotHandled);
  905. }
  906.  
  907.  
  908. //////////
  909. //
  910. // HandleQuitApplicationAppleEvent 
  911. // Handle the quit-application Apple event.
  912. //
  913. //////////
  914.  
  915. PASCAL_RTN OSErr HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  916. {
  917. #pragma unused(theMessage, theReply, theRefcon)
  918.  
  919.     // close down the entire framework and application
  920.     QuitFramework();
  921.     return(noErr);
  922. }
  923. #endif    // TARGET_OS_MAC
  924.  
  925.